from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework_jwt.settings import api_settings

from users.utils import get_user_by_account
from rest_framework import status as http_status
from luffyapi.libs.geetest import GeetestLib
#请在官网申请ID使用，示例ID不可使用
pc_geetest_id = "d4904eec9e43a457a15f94c755d94f90"
pc_geetest_key = "d35f599fb02f7a6ce9597908d2d0eab4"


import random
from rest_framework import status
from django_redis import get_redis_connection



from rest_framework.generics import CreateAPIView
from .models import Userss
from .serializers import UserModelSerializer
class UserAPIView(CreateAPIView):
    """用户信息视图"""
    queryset = Userss.objects.all()
    serializer_class = UserModelSerializer



class MobileAPIView(APIView):
    def get(self,request,mobile):
        ret = get_user_by_account(mobile)
        if ret is not None:
            return Response({"message":"手机号已经被注册过！"},status=status.HTTP_400_BAD_REQUEST)
        return Response({"message":"ok"})



class CaptchaAPIView(APIView):
    """验证码视图类"""
    status = False
    user_id = 0
    def get(self,request):
        """获取验证码"""
        username = request.query_params.get("username")
        # print(username)
        user = get_user_by_account(username)
        if user is None:
            return Response({"message": "对不起，用户不存在！"}, status=http_status.HTTP_400_BAD_REQUEST)

        self.user_id = user.id
        gt = GeetestLib(pc_geetest_id, pc_geetest_key)
        self.status = gt.pre_process(self.user_id)
        # todo 后面增加status和user_id保存到redis数据库
        response_str = gt.get_response_str()
        return Response(response_str)

    def post(self,request):
        """验证码的验证方法"""
        gt = GeetestLib(pc_geetest_id, pc_geetest_key)
        challenge = request.POST.get(gt.FN_CHALLENGE, '')
        validate = request.POST.get(gt.FN_VALIDATE, '')
        seccode = request.POST.get(gt.FN_SECCODE, '')
        if self.status:
            result = gt.success_validate(challenge, validate, seccode, self.user_id)
        else:
            result = gt.failback_validate(challenge, validate, seccode)
        result = {"status":"success"} if result else {"status":"fail"}
        return Response(result)


from luffyapi.settings import constants
from mycelery.main import app
from luffyapi.libs.yuntongxun.ccp_sms import CPP
class SMSAPIView(APIView):
    """
    发送短信
    """
    def get(self,request,mobile):

        # 接收手机号码以后，验证是否已经注册
        try:
            Userss.objects.get(mobile=mobile)
            return Response("当前手机号已被注册！", status=status.HTTP_400_BAD_REQUEST)
        except:
            pass



        # 引入redis
        redis = get_redis_connection("sms_code")

        # 判断当前手机号码是否曾经在60s发送过短信
        # print(mobile)
        mobile_intervel = redis.get("mobile_%s" % mobile)
        if mobile_intervel is not None:
            return Response({"result":"对不起~手机短信发送间隔不足1分钟!"},status=status.HTTP_400_BAD_REQUEST)

        # 生成短信号码并把短信和手机号码保存到redis中
        code = "%04d" % random.randint(0, 9999)
        # 在以后开发中如果一次性要写入多条redis命令，建议采用道操作[事务操作]来把多条数据整理成一块，一并发送给redis
        pip = redis.pipeline()
        # 开启事务【无法管理数据库的读取数据操作】
        pip.multi()

        # 设置短信发送间隔时间
        # setex mobile_17776445415 60 _
        pip.setex("mobile_%s" % mobile, constants.SEND_SMS_CODE_INTERVAL, "_") # "_" 表示占位符，没有任何意义的


        # print(1)
        # 可以使用string格式进行数据保存
        # setex sms_17776445415 300 666666
        pip.setex("sms_%s" % mobile, constants.SMS_CODE_REDIS_EXPIRES, code)
        # print(1)

        # 执行管道中的所有命令[提交事务]
        pip.execute()
        # print(1)

        # 4. 调用短信sdk，发送短信
        try:
            from mycelery.sms.tasks import send_sms
            # print(mobile)
            send_sms(mobile,code)

            # ccp = CPP()
            # ret = ccp.sendTemplateSMS(mobile, [code, constants.SEND_SMS_CODE_INTERVAL], constants.SEND_SMS_TEMPLATE_ID)
            # # ret = 0
            # if ret == -1:
            #     # log.error("用户注册短信发送失败！手机号：%s" % mobile)
            #     return Response({"message":"发送短信失败！"},status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        except:
            return Response({"message": "发送短信失败！"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        # 5. 响应发送短信的结果
        return Response({"message": "发送短信成功！"})


class SMSMAPIView(APIView):
    def get(self,request,mobile):

        ret = Userss.objects.filter(mobile=mobile).count()
        # print(ret)
        if ret == 0:
            return Response({"message": "当前手机号未注册"}, status=status.HTTP_400_BAD_REQUEST)

        # print(1)
        # 引入redis
        redis = get_redis_connection("sms_code")

        # 生成短信号码并把短信和手机号码保存到redis中
        code = "%04d" % random.randint(0, 9999)

        # 在以后开发中如果一次性要写入多条redis命令，建议采用道操作[事务操作]来把多条数据整理成一块，一并发送给redis
        pip = redis.pipeline()
        # 开启事务【无法管理数据库的读取数据操作】
        pip.multi()

        # 设置短信发送间隔时间
        # setex mobile_17776445415 60 _
        pip.setex("sms_%s" % mobile, constants.SMS_CODE_REDIS_EXPIRES, code)

        # 执行管道中的所有命令[提交事务]
        pip.execute()

        # 发送短信验证码
        from mycelery.sms.tasks import send_sms

        send_sms(mobile, code)

        # ccp = CPP()
        # ret = ccp.sendTemplateSMS(mobile, [code, constants.SEND_SMS_CODE_INTERVAL], constants.SEND_SMS_TEMPLATE_ID)

        print("登录的短信验证码为====",code)

        return Response({"message": "发送短信成功！"},status=status.HTTP_200_OK)


class YZMAPIView(APIView):
    def post(self,request):
        mobile = request.data.get("mobile")
        yzm = request.data.get("yzm")
        # print(mobile)
        # 引入redis
        redis = get_redis_connection("sms_code")

        # 读取redis中的验证码
        yuy = redis.get("sms_%s" % mobile).decode()


        # print("redis数据库中的验证码为===",yuy)

        if yzm != yuy:
            return Response({"message": "输入的验证码错误"}, status=status.HTTP_400_BAD_REQUEST)
        else:
            from users.Pyjwt import generate_jwt_token
            # jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
            # jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
            #
            # payload = jwt_payload_handler(mobile)
            # mobile.token = jwt_encode_handler(payload)
            set = generate_jwt_token(mobile).decode()
            ete = Userss.objects.filter(mobile=mobile)
            # sete = [{'id':item.id,'username':item.username} for item in ete]
            # print(ete)
            # print(sete)

            for item in ete:
                dic = {"token":set,"id":item.id,"username":item.username}
                # print(dic)
                return Response({"message": "登录成功！",'data':dic}, status=status.HTTP_200_OK)











